/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.stores.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinyeit.serviceapp.entity.ReceivePaymentDetail;
import com.qinyeit.serviceapp.entity.StoreInOrder;
import com.qinyeit.serviceapp.entity.StoreOutOrder;
import com.qinyeit.serviceapp.entity.enums.PaymentState;
import com.qinyeit.serviceapp.entity.enums.PaymentType;
import com.qinyeit.serviceapp.entity.enums.ReceivePaymentType;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.repository.stores.ReceivePaymentDetailRepository;
import com.qinyeit.serviceapp.service.stores.StoreInOrderService;
import com.qinyeit.serviceapp.service.stores.StoreOutOrderService;
import com.qinyeit.serviceapp.utils.CompuUtils;
import com.qinyeit.serviceapp.utils.LocalUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.qinyetech.springstage.core.service.BaseService;
import com.qinyeit.serviceapp.entity.ReceivePayment;
import com.qinyeit.serviceapp.repository.stores.ReceivePaymentRepository;
import com.qinyeit.serviceapp.service.stores.ReceivePaymentService;

import java.util.List;
import java.util.stream.Collectors;

/** 
 * ClassName: ReceivePaymentServiceImpl <br/> 
 * Function: 供应商收付款单据 业务实现 <br/> 
 * date: 2019-03-05 10:06:09 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class ReceivePaymentServiceImpl extends BaseService<ReceivePayment, Long> implements ReceivePaymentService {


	@Autowired
	private ReceivePaymentRepository receivePaymentRepository;
	@Autowired
	private StoreInOrderService storeInOrderService;
	@Autowired
	private StoreOutOrderService storeOutOrderService;
	@Autowired
	private ReceivePaymentDetailRepository receivePaymentDetailRepository;


    @Override
    public void saveData(JSONObject data, Long merchantGroupId,String operator) {
        if(data==null){
            throw new BusinessRunTimeException("提交的数据为空",10001);
        }
        JSONObject orderData = data.getJSONObject("order");
        JSONArray details = data.getJSONArray("details");

        if (orderData==null){
            throw new BusinessRunTimeException("订单数据为空",100001);
        }

        if(CollectionUtils.isEmpty(details)){
            throw new BusinessRunTimeException("订单明细为空",10002);
        }

        if(StringUtils.isBlank(orderData.getString("supplierName"))){
            throw new BusinessRunTimeException("请选择供应商",10003);
        }
        ReceivePayment payment = new ReceivePayment();
        payment.setNo(LocalUtils.getOrderNo());
        payment.setSupplierId(orderData.getLong("supplierId"));
        payment.setSupplierName(orderData.getString("supplierName"));
        payment.setOperatorTime(DateUtils.date());
        payment.setOperatorName(operator);
        payment.setType(ReceivePaymentType.valueOf(orderData.getString("type")));
        payment.setMerchantGroupId(merchantGroupId);
        payment.setRemark(orderData.getString("remark"));

        JSONObject item ;
        ReceivePaymentDetail detail = null;
        StoreOutOrder storeOutOrder = null;
        StoreInOrder storeInOrder = null;
        double cha;
        double amount=0 ;
        double giftamount=0 ;
        double payamount=0;
        List<ReceivePaymentDetail> detailList = Lists.newArrayList();
        for (int i = 0; i < details.size(); i++) {
            item = details.getJSONObject(i);
            detail = new ReceivePaymentDetail();
            if(item.getLong("id")==null){
                throw new BusinessRunTimeException("数据错误,订单不存在",10001);
            }
            storeInOrder=null;
            storeOutOrder=null;
            if(payment.getType()==ReceivePaymentType.STOREIN){
                storeInOrder = storeInOrderService.findById(item.getLong("id"));
                if(storeInOrder==null){
                    throw new BusinessRunTimeException("数据错误，订单不存在",10002);
                }
                detail.setOrderNo(storeInOrder.getNo());
                detail.setOrderAmount(storeInOrder.getAmount());
                payamount = CompuUtils.add(storeInOrder.getPayAmount(),storeInOrder.getGiftAmount());
            }else {
                storeOutOrder = storeOutOrderService.findById(item.getLong("id"));
                if(storeOutOrder==null){
                    throw new BusinessRunTimeException("数据错误，订单不存在",10002);
                }
                detail.setOrderNo(storeOutOrder.getNo());
                detail.setOrderAmount(storeOutOrder.getAmount());
                payamount = CompuUtils.add(storeOutOrder.getPayAmount(),storeOutOrder.getGiftAmount());
            }
            detail.setOrder(payment);
            detail.setAmount(item.getDouble("amount"));
            detail.setGiftAmount(item.getDouble("giftAmount"));
            detail.setRemark(item.getString("remark"));
            cha = CompuUtils.add(2,detail.getOrderAmount(),detail.getAmount()*(-1),payamount*(-1),detail.getGiftAmount()*(-1));
            log.info("____________cha : {}",cha);
            if(cha<0){
                throw new BusinessRunTimeException("收款金额不能大于订单金额",10003);
            }
            if(cha==0){
                detail.setPaymentState(PaymentState.SETTLED);
            }else {
                detail.setPaymentState(PaymentState.NORMAL);
            }
            detailList.add(detail);
            amount = CompuUtils.add(amount,detail.getAmount());
            giftamount = CompuUtils.add(giftamount,detail.getGiftAmount());

            //修改订单的金额
            if(payment.getType()==ReceivePaymentType.STOREIN){
               updateStoreInOrder(storeInOrder,detail);
            }else {
               updateStoreOutOrder(storeOutOrder,detail);
            }


        }

        payment.setAmount(amount);
        payment.setGiftAmount(giftamount);
        payment = this.save(payment);
        receivePaymentDetailRepository.saveAll(detailList);
    }

    /**
     * 总部出库 修改订单金额
     * @param storeOutOrder
     * @param detail
     */
    private void updateStoreOutOrder(StoreOutOrder storeOutOrder, ReceivePaymentDetail detail) {
        if(storeOutOrder==null){
            throw new BusinessRunTimeException("清单不存在",10001);
        }
        storeOutOrder.setPayAmount(CompuUtils.add(storeOutOrder.getPayAmount(),detail.getAmount()));
        storeOutOrder.setGiftAmount(CompuUtils.add(storeOutOrder.getGiftAmount(),detail.getGiftAmount()));
        storeOutOrder.setPaymentState(detail.getPaymentState());
        storeOutOrderService.update(storeOutOrder);
    }

    /**
     * 总部入库 修改订单金额
     * @param storeInOrder
     * @param detail
     */
    private void updateStoreInOrder(StoreInOrder storeInOrder, ReceivePaymentDetail detail) {
        if(storeInOrder==null){
            throw new BusinessRunTimeException("清单不存在",10001);
        }
        storeInOrder.setPayAmount(CompuUtils.add(storeInOrder.getPayAmount(),detail.getAmount()));
        storeInOrder.setGiftAmount(CompuUtils.add(storeInOrder.getGiftAmount(),detail.getGiftAmount()));
        storeInOrder.setPaymentState(detail.getPaymentState());
        storeInOrderService.update(storeInOrder);
    }
}